import axios from "axios";

// class Queue {
//   constructor() {
//     this._queue = [];
//   }

//   push(value) {
//     return this._queue.push(value);
//   }

//   shift() {
//     return this._queue.shift();
//   }

//   isEmpty() {
//     return this._queue.length === 0;
//   }
// }
class HighPerformanceQueue {
  constructor() {
    this.q1 = []; // 用于 push 数据
    this.q2 = []; // 用于 shift 数据
  }

  push(value) {
    return this.q1.push(value);
  }

  shift() {
    let q2 = this.q2;
    if (q2.length === 0) {
      const q1 = this.q1;
      if (q1.length === 0) {
        return;
      }
      this.q1 = q2;
      q2 = this.q2 = q1.reverse();
    }

    return q2.pop();
  }

  isEmpty() {
    if (this.q1.length === 0 && this.q2.length === 0) {
      return true;
    }
    return false;
  }
}

class DelayedTask {
  constructor(resolve, fn, args) {
    this.resolve = resolve;
    this.fn = fn;
    this.args = args;
  }
}
class TaskPool {
  constructor(size) {
    this.size = size;
    // this.queue = new Queue();
    this.queue = new HighPerformanceQueue();
  }

  // addTask(fn, args) {
  //   return new Promise((resolve) => {
  //     this.queue.push(new DelayedTask(resolve, fn, args));
  //     if (this.size) {
  //       this.size--;
  //       const { resolve: taskResole, fn, args } = this.queue.shift();
  //       taskResole(this.runTask(fn, args));
  //     }
  //   });
  // }

  addTask(fn) {
    return (...args) => {
      return new Promise((resolve) => {
        this.queue.push(new DelayedTask(resolve, fn, args));

        if (this.size) {
          this.size--;
          const {
            resolve: taskResole,
            fn: taskFn,
            args: taskArgs,
          } = this.queue.shift();
          taskResole(this.runTask(taskFn, taskArgs));
        }
      });
    };
  }

  pullTask() {
    if (this.queue.isEmpty()) {
      return;
    }

    if (this.size === 0) {
      return;
    }

    this.size++;
    const { resolve, fn, args } = this.queue.shift();
    resolve(this.runTask(fn, args));
  }

  runTask(fn, args) {
    const result = Promise.resolve(fn(...args));

    result
      .then(() => {
        this.size--;
        this.pullTask();
      })
      .catch(() => {
        this.size--;
        this.pullTask();
      });

    return result;
  }
}

// const task = (timeout) =>
//   new Promise((resolve) =>
//     setTimeout(() => {
//       resolve(timeout);
//     }, timeout)
//   );
const task = (timeout) => {
  return new Promise((resolve, reject) => {
    try {
      axios.get("/api/banners/1").then((res) => {
        resolve(res);
      });
    } catch (error) {
      reject(error);
    }
  });
};

const taskList = [
  1000, 3000, 200, 1300, 800, 2000, 2, 2, 2, 22, 2, 2, 2, 2, 22, 2, 2, 2, 22, 2,
  2, 2, 22, 2, 2, 2, 2, 2, 2, 2, 2, 22, 2, 2, 2, 1,
];

const cc = new TaskPool(10);

async function startConcurrentControl() {
  console.time("CONCURRENT_CONTROL_LOG");

  // const res = await Promise.all(taskList.map(cc.addTask(task)));

  const res = await Promise.all(taskList.map(cc.addTask(task)));
  console.timeEnd("CONCURRENT_CONTROL_LOG");
  console.log(res);
}

startConcurrentControl();
